package models;

import java.lang.reflect.Type;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.PostPersist;
import javax.persistence.Table;

import play.db.jpa.Model;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

import event.EventHandler;

@Entity
@Table(name="Orderr")
public class Order extends Model {
	@Column(nullable=false)
	private Date orderDate;
	
	@ManyToOne(optional=false, fetch=FetchType.LAZY)
	private Establishment establishment;

	@ManyToOne(optional=false, fetch=FetchType.LAZY)
	private Customer customer;
	
	@OneToMany(cascade=CascadeType.ALL, mappedBy="order", orphanRemoval=true, fetch=FetchType.LAZY)
	private Set<OrderItem> items;

	@OneToOne(optional=false, fetch=FetchType.LAZY)
	private DeliverySpot deliverySpot;

	public Establishment getEstablishment() {
		return establishment;
	}

	public void setEstablishment(Establishment establishment) {
		this.establishment = establishment;
	}

	public Set<OrderItem> getItems() {
		return items;
	}

	public void setItems(Set<OrderItem> items) {
		this.items = items;
	}

	public Customer getCustomer() {
		return customer;
	}

	public void setCustomer(Customer customer) {
		this.customer = customer;
	}

	public DeliverySpot getDeliverySpot() {
		return deliverySpot;
	}

	public void setDeliverySpot(DeliverySpot deliverySpot) {
		this.deliverySpot = deliverySpot;
	}

	public Date getOrderDate() {
		return orderDate;
	}

	public void setOrderDate(Date orderDate) {
		this.orderDate = orderDate;
	}

	@PostPersist
	private void storeS3() {
		OrderJsonSerializer serializer =  new OrderJsonSerializer();
		EventHandler.notifyOrderIcoming(serializer.serialize(this, null, null).toString());
	}

	public static class OrdersJsonSerializer implements JsonSerializer<List<Order>> {
		@Override
		public JsonElement serialize(List<Order> orders, Type type,
				JsonSerializationContext context) {
			
			JsonArray json = new JsonArray();
			OrderJsonSerializer jsonSerializer = new OrderJsonSerializer();
			
			for (Order order : orders) {
				json.add(jsonSerializer.serialize(order, type, context));
			}
			
			return json;
		}
	}
	
	public static class OrderJsonSerializer implements JsonSerializer<Order> {
		@Override
		public JsonElement serialize(Order order, Type type,
				JsonSerializationContext context) {
			JsonObject json =  new JsonObject();
			
			JsonObject establishment = new JsonObject();
			establishment.addProperty("id", order.getEstablishment().getId());
			establishment.addProperty("name", order.getEstablishment().getName());

			JsonObject customer = new JsonObject();
			customer.addProperty("id", order.getCustomer().getId());
			customer.addProperty("name", order.getCustomer().getName());
			
			JsonObject deliverySpot =  new JsonObject();
			JsonArray deliverySpotValues = new JsonArray();
			
			for (DeliverySpotValues values : order.getDeliverySpot().getValues()) {
				JsonObject jsonValues = new JsonObject();
				jsonValues.addProperty("name", values.getDeliverySpotValuesId().getAttribute().getName());
				jsonValues.addProperty("value", values.getValue());
				
				deliverySpotValues.add(jsonValues);
			}
			deliverySpot.add("deliverySpotValues", deliverySpotValues);
			
			JsonArray items = new JsonArray();
			
			for (OrderItem item : order.getItems()) {
				JsonObject itemJson = new JsonObject();
				itemJson.addProperty("qtd", item.getQtd());
				itemJson.addProperty("detail", item.getDetail());
				itemJson.addProperty("unitPrice", item.getUnitPrice());
				JsonObject menuItem = new JsonObject();
				menuItem.addProperty("name", item.getItem().getName());
				menuItem.addProperty("id", item.getItem().getId());
				itemJson.add("menuItem", menuItem);
				
				items.add(itemJson);
			}
			
			json.addProperty("id", order.getId());
			json.add("establishment", establishment);
			json.add("customer", customer);
			json.add("deliverySpot", deliverySpot);
			json.add("items", items);

			return json;
		}
	}
	
	public static void main(String[] args) {
		System.out.println(new Date().getTime());
	}
}
